Skip to content

Conversation

Michael137
Copy link
Member

This patch factors out the code to create a DIExpression from an APValue into a separate helper function.

This will be useful in a follow-up patch where we re-use this logic elsewhere.

Pre-requisite for #70639

This patch factors out the code to create a DIExpression from
an APValue into a separate helper function.

This will be useful in a follow-up patch where we re-use this
logic elsewhere.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. debuginfo labels Oct 30, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 30, 2023

@llvm/pr-subscribers-clang
@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-clang-codegen

Author: Michael Buch (Michael137)

Changes

This patch factors out the code to create a DIExpression from an APValue into a separate helper function.

This will be useful in a follow-up patch where we re-use this logic elsewhere.

Pre-requisite for #70639


Full diff: https://github.com/llvm/llvm-project/pull/70674.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+26-18)
  • (modified) clang/lib/CodeGen/CGDebugInfo.h (+5)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0aaf678bf287c6e..9de55e41f885d26 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5580,25 +5580,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
   auto &GV = DeclCache[VD];
   if (GV)
     return;
-  llvm::DIExpression *InitExpr = nullptr;
-  if (CGM.getContext().getTypeSize(VD->getType()) <= 64) {
-    // FIXME: Add a representation for integer constants wider than 64 bits.
-    if (Init.isInt()) {
-      const llvm::APSInt &InitInt = Init.getInt();
-      std::optional<uint64_t> InitIntOpt;
-      if (InitInt.isUnsigned())
-        InitIntOpt = InitInt.tryZExtValue();
-      else if (auto tmp = InitInt.trySExtValue(); tmp.has_value())
-        // Transform a signed optional to unsigned optional. When cpp 23 comes,
-        // use std::optional::transform
-        InitIntOpt = (uint64_t)tmp.value();
-      if (InitIntOpt)
-        InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value());
-    } else if (Init.isFloat())
-      InitExpr = DBuilder.createConstantValueExpression(
-          Init.getFloat().bitcastToAPInt().getZExtValue());
-  }
 
+  llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init);
   llvm::MDTuple *TemplateParameters = nullptr;
 
   if (isa<VarTemplateSpecializationDecl>(VD))
@@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const {
 
   return llvm::DINode::FlagAllCallsDescribed;
 }
+
+llvm::DIExpression *
+CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD,
+                                           const APValue &Val) {
+  llvm::DIExpression *ValExpr = nullptr;
+  if (CGM.getContext().getTypeSize(VD->getType()) <= 64) {
+    // FIXME: Add a representation for integer constants wider than 64 bits.
+    if (Val.isInt()) {
+      const llvm::APSInt &ValInt = Val.getInt();
+      std::optional<uint64_t> ValIntOpt;
+      if (ValInt.isUnsigned())
+        ValIntOpt = ValInt.tryZExtValue();
+      else if (auto tmp = ValInt.trySExtValue(); tmp.has_value())
+        // Transform a signed optional to unsigned optional. When cpp 23 comes,
+        // use std::optional::transform
+        ValIntOpt = (uint64_t)tmp.value();
+      if (ValIntOpt)
+        ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value());
+    } else if (Val.isFloat())
+      ValExpr = DBuilder.createConstantValueExpression(
+          Val.getFloat().bitcastToAPInt().getZExtValue());
+  }
+
+  return ValExpr;
+}
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index ae12485850ca775..7b60e94555d0608 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -800,6 +800,11 @@ class CGDebugInfo {
                            llvm::MDTuple *&TemplateParameters,
                            llvm::DIScope *&VDContext);
 
+  /// Create a DIExpression representing the constant corresponding
+  /// to the specified 'Val'. Returns nullptr on failure.
+  llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD,
+                                                    const APValue &Val);
+
   /// Allocate a copy of \p A using the DebugInfoNames allocator
   /// and return a reference to it. If multiple arguments are given the strings
   /// are concatenated.

Copy link
Contributor

@felipepiovezan felipepiovezan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but left a couple of comments.
Thanks for breaking this into two separate PRs.

llvm::DIExpression *
CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD,
const APValue &Val) {
llvm::DIExpression *ValExpr = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is how the original code was written, but since we are making a separate function we are now in a position where we can delete this line, early-return on the if and replace all assignments to ValExpr with return statements.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do

Comment on lines 5939 to 5945
if (ValIntOpt)
return DBuilder.createConstantValueExpression(ValIntOpt.value());
} else if (Val.isFloat())
return DBuilder.createConstantValueExpression(
Val.getFloat().bitcastToAPInt().getZExtValue());

return nullptr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could modify this a bit to simplify indentation, maye:

if (Val.isFloat())
  return DBUilder.createConstantValueExpression(...);
const llvm::APSInt &ValInt = Val.getInt();
...
if (ValIntOpt)
  return DBuilder.createConstantValueExpression(*ValIntOpt);
return nullptr;

std::optional<uint64_t> ValIntOpt;
if (ValInt.isUnsigned())
ValIntOpt = ValInt.tryZExtValue();
else if (auto tmp = ValInt.trySExtValue(); tmp.has_value())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit redundant/equivalent to:

else if (auto tmp = ValInt.trySExtValue())

else if (auto tmp = ValInt.trySExtValue(); tmp.has_value())
// Transform a signed optional to unsigned optional. When cpp 23 comes,
// use std::optional::transform
ValIntOpt = (uint64_t)tmp.value();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably write this as (uint64_t)*tmp

Copy link
Collaborator

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great - thanks!

@Michael137 Michael137 merged commit aa8a0c0 into llvm:main Nov 6, 2023
@Michael137 Michael137 deleted the inline-statics-support/clang-debug-info-nfc branch November 6, 2023 09:22
@Michael137 Michael137 restored the inline-statics-support/clang-debug-info-nfc branch November 6, 2023 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category debuginfo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants